* Makefile.am

~Makefile.am~ looks like a normal ~Makefile~ in terms of syntax. This language
is apparently [[https://www.gnu.org/savannah-checkouts/gnu/m4/manual/m4-1.4.18/index.html][M4]], using the [[https://www.gnu.org/software/m4/][GNU M4]] implementation, an implementation of a Unix
macro processor. Apparently [[https://www.gnu.org/software/autoconf/autoconf.html][GNU Autoconf]] and therefore the files ~Makefile.am~,
~Makefile.in~, ~Makefile~ and ~configure.ac~ all make use of this language:

#+NAME: autoconf-website-quote
#+begin_quote
Autoconf is an extensible package of M4 macros that produce shell scripts to
automatically configure software source code packages. These scripts can adapt
the packages to many kinds of UNIX-like systems without manual user
intervention. Autoconf creates a configuration script for a package from a
template file that lists the operating system features that the package can use,
in the form of M4 macro calls.

-- https://www.gnu.org/software/autoconf/autoconf.html
#+end_quote

* Why guile-haunt?

~guile-haunt~ is a static site generator written in GNU Guile only. It is
available on GNU Guix, so it should make for a good example for how one can
build a GNU Guix package oneself. It also was a package recommended to look at
on the GNU Guile IRC channel.

The repository can be found here: [[https://github.com/guildhall/guile-haunt]].

* Explanations

So lets go. Lets try to explain what the various parts, that we can find in the
~guile-haunt~ project, that are taking part in making a GNU Guix package, do.

** GNU Guile source files

Apparently one ships the source files with the package, so the source files need
to be defined somewhere.

 #+begin_src makefile
SOURCES =					\
  haunt/config.scm				\
  haunt/utils.scm				\
  haunt/post.scm				\
  haunt/reader.scm				\
  haunt/page.scm				\
  haunt/asset.scm				\
  haunt/site.scm				\
  haunt/html.scm				\
  haunt/builder/assets.scm			\
  haunt/builder/atom.scm			\
  haunt/builder/blog.scm			\
  haunt/ui.scm					\
  haunt/ui/build.scm				\
  haunt/ui/serve.scm				\
  haunt/serve/mime-types.scm			\
  haunt/serve/web-server.scm
 #+end_src

 This seems to simply be a list of all GNU Guile source files and is fittingly
 named ~SOURCES~.

** GNU Guile compiled files

GNU Guile source files are compiled to Guile object files, which have the file
extension ~.go~. The following rules of the form ~$(var:a=b)~ is a so called
"substitution reference" (See also
[[https://www.gnu.org/software/make/manual/make.html#Substitution-Refs]]):

#+begin_src makefile
GOBJECTS = $(SOURCES:%.scm=%.go)
#+end_src

This rule says: For each item in ~SOURCES~, which has the form ~%.scm~, put a
new item in ~GOBJECTS~, which has the form ~%.go~. ~%.scm~ matches all filenames
with the extension ~.scm~.

So this is an easy way of saying ~GOBJECTS~ are the Guile object files, which
correspond to the ~SOURCES~ files.

** Extra distributed files

Extra distributed files are files, which are not source code of the library or
program itself, but files, which nevertheless should be put into the
package. Such files are readme files initialization files and a ~package.scm~
file, which suspiciously looks like a file GNU Guix might be looking for
already.

Additionally to the compiled sources, the sources and not compiled sources get
distributed.

 #+begin_src makefile
EXTRA_DIST = $(SOURCES) $(NOCOMP_SOURCES)

EXTRA_DIST +=					\
  pre-inst-env.in				\
  README.md					\
  package.scm
 #+end_src

** Sub directories

For some reason (TODO) the sub directories of the project need to be specified.

#+begin_src makefile
SUBDIRS =					\
  example					\
  website
#+end_src

** Scripts

The situation with ~guile-haunt~ is a little different from a simple library,
because it is a command line tool, which is supposed to be invoked by the user.

However, ~guile-haunt~ is not intended to be called by calling ~guile~ and then
specifying the directory, which ~guile-haunt~ and the main source file are
installed in. This would be a bit cumbersome for users. Instead the idea is to
provide a script, which is on the ~PATH~ and can be run. This script should
accept the same arguments that the actual ~guile-haunt~ program accepts and hand
them over to ~guile-haunt~.

Such a script is located in the ~scripts~ directory inside the project.

TODO: I am not sure, why it needs to be specified in the ~Makefile.am~ file.

 #+begin_src makefile
bin_SCRIPTS =					\
  scripts/haunt
 #+end_src

*** haunt script

The actual script has the following content:

#+begin_src guile
#!@GUILE@ --no-auto-compile
-*- scheme -*-
!#
;;; Haunt --- Static site generator for GNU Guile
;;; Copyright © 2015 David Thompson <davet@gnu.org>
;;;
;;; This file is part of Haunt.
;;;
;;; Haunt is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or
;;; (at your option) any later version.
;;;
;;; Haunt is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;;; General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with Haunt.  If not, see <http://www.gnu.org/licenses/>.

(use-modules (haunt ui))
(apply haunt-main (command-line))
#+end_src

It looks like the hash-bang line refers to Guile, not directly, but via a
template variable or something. Perhaps the script is merely a template, which
is filled in later?

TODO: explain

The Guile code itself is quite simple.

#+begin_src scheme
(use-modules (haunt ui))
(apply haunt-main (command-line))
#+end_src

It loads the module ~(haunt ui)~ and then applies the project's main function to
the command line arguments.

** Directory of compiled GNU Guile files

GNU Guile source files are compiled to Guile object files, which have the file
extension ~.go~. The directory, in which those files can be found also is
specified in the ~Makefile.am~.

TODO: I am not sure, why this directory needs to be specified in the
~Makefile.am~ file.

#+begin_src makefile
godir=$(libdir)/guile/2.0/ccache
#+end_src

** Modules directory

The modules directory is the directory, in which the GNU Guile source files will
be put, when the package is installed. It is specified as well:

#+begin_src makefile
moddir=$(prefix)/share/guile/site/2.0
#+end_src

** Cleaning up

Since GNU Guile scheme files are compiled to ~.go~, one can force a recompile of
the source by deleting the ~.go~ files, when they are needed next time.

#+begin_src makefile
CLEANFILES = $(GOBJECTS)
#+end_src

** Compilation flags

Some flags about warning output at compile time of sources are specified and
given the name ~GUILE_WARNINGS~:

#+begin_src makefile
GUILE_WARNINGS = -Wunbound-variable -Warity-mismatch -Wformat
#+end_src

They are later used in the target ~.scm.go~.

** File endings

A list of file endings is defined:

#+begin_src makefile
SUFFIXES = .scm .go
#+end_src

TODO: I do not know yet, why the ~SUFFIXES~ are defined.

** Targets

There are many definitions, but only a few actual targets in the ~Makefile.am~
of ~guile-haunt~:

1. ~$(guile_install_go_files)~
2. ~.scm.go~

That is it.

TODO: I do not know yet, why the files have a combined file ending of ~.scm~ and
then ~.go~ instead of only ~.go~. Perhaps this is a common convention?

** Compilation command

At some point there needs to be an instruction that tells GNU Guix how to
actually compile the program. This instruction is a target defined as follows:

#+begin_src makefile
.scm.go:
	$(AM_V_GEN)$(top_builddir)/pre-inst-env $(GUILE_TOOLS) compile $(GUILE_WARNINGS) -o "$@" "$<"
#+end_src

~AM_V_GEN~ stands Apparently for "automake" (see: [[https://www.gnu.org/software/automake/manual/automake.html#amhello_0027s-configure_002eac-Setup-Explained][Automake hello]]) then perhaps
~V~ for "verbosity", then perhaps ~GEN~ for "generate". So a string, which gets
inserted, which contains instructions for the verbosity of the command to only
show what it generated. Prepending it to a command will output only ~GEN
TARGET~, where ~TARGET~ is the created file which is the target. In this case
the output should be ~GEN ....scm.go~ for each ~.scm.go~ file. ~AM_V_GEN~ is
probably predefined in automake.

Here is an explanation for ~AM_V_GEN~ from the Automake manual:

#+begin_quote
You can use the predefined variable AM_V_GEN as a prefix to commands that should
output a status line in silent mode, and AM_V_at as a prefix to commands that
should not output anything in silent mode. When output is to be verbose, both of
these variables will expand to the empty string.

-- https://www.gnu.org/software/automake/manual/automake.html#amhello_0027s-configure_002eac-Setup-Explained
#+end_quote

~top_builddir~ appears in 2 places in the repository:

- thrice in the pre-installation environment:

  #+begin_src shell
  ...
  abs_top_builddir="`cd "@abs_top_builddir@" > /dev/null; pwd`"
  ...
  GUILE_LOAD_COMPILED_PATH="$abs_top_builddir${GUILE_LOAD_COMPILED_PATH:+:}$GUILE_LOAD_COMPILED_PATH"
  ...
  PATH="$abs_top_builddir/scripts:$PATH"
  #+end_src

- in its usage in the ~Makefile.am~

TODO: What is the ~@VARNAME@~ syntax in the shell script? Is this normal shell
script syntax?

TODO: Where does ~top_builddir~ come from?

TODO: Where does ~GUILE_TOOLS~ come from? It is only mentioned in its definition
in the ~Makefile.am~.

TODO: Explain ~"$@"~.  TODO: Explain ~"$<"~.

** Still unexplained

There are still some parts missing from a full explanation:

#+begin_src makefile
nobase_mod_DATA = $(SOURCES) $(NOCOMP_SOURCES)
nobase_go_DATA = $(GOBJECTS)

# Make sure source files are installed first, so that the mtime of
# installed compiled files is greater than that of installed source
# files.  See
# <http://lists.gnu.org/archive/html/guile-devel/2010-07/msg00125.html>
# for details.
guile_install_go_files = install-nobase_goDATA
$(guile_install_go_files): install-nobase_modDATA
#+end_src

~nobase_mod_DATA~ only appears once in the whole repository of ~guile-haunt~,
which is in its definition in the ~Makefile.am~. It therefore seems, that it is
something GNU Guix is looking for in a ~Makefile~, which is produced from the
~Makefile.am~. Looking at [[https://www.gnu.org/software/automake/manual/automake.html#Creating-amhello][Creating amhello]] in the GNU automake manual, it seems,
that there is a convention, by which one appends ~_DATA~ to some
variables. Perhaps those are always data for other tools to access later, when
they work with the resulting ~Makefile~.

Same goes for ~nobase_go_DATA~. It also only appears in its definition and seems
to be data for later usage.

- TODO: What is ~nobase~ relating to? What would be "the base", of which there
  is none here?

- TODO: Where does ~install-nobase_modDATA~ come from? Is it relating to
  ~nobase_go_DATA~ and the ~install-~ prefix is magically taken off? ~go~
  probably stands for "GNU Guile object file".

- TODO: Where does ~install-nobase_goDATA~ come from? Is it relating to
  ~nobase_mod_DATA~ and the ~install-~ prefix magically taken off? ~mod~ might
  stand for "GNU Guile module".

- TODO: But why? How does GNU Guix make use of these variables?

- TODO: What does it mean, that ~install-nobase_modDATA~ depends on
  ~guile_install_go_files~?

* Makefile syntax

- Reasons to use ~@:~: [[https://stackoverflow.com/a/16818821]]
